package com.rslai.base.tool.servertest.statement;

import com.rslai.base.tool.servertest.ServertestFrameworkMethod;
import com.rslai.base.tool.servertest.command.StepCommand;
import com.rslai.base.tool.servertest.event.StepNotifier;
import com.rslai.base.tool.servertest.model.TestCase;
import com.rslai.base.tool.servertest.reporter.ParseCase;
import com.rslai.base.tool.servertest.reporter.QJSONReporter;
import com.rslai.base.tool.servertest.reporter.Reporter;

import java.util.List;
import java.util.Map;

import org.junit.runners.model.Statement;

public class ServertestStatement extends Statement {
    private ServertestFrameworkMethod frameworkMethod;
    private Reporter reporter;

    public ServertestStatement(ServertestFrameworkMethod frameworkMethod, Reporter rpt) {
        this.frameworkMethod = frameworkMethod;
        this.reporter = rpt;
    }

    public void evaluate() throws Throwable {
        StepNotifier sNotifier = new StepNotifier();
        sNotifier.addStepEventListener(this.reporter.createStepListener());
        TestCase testCase = this.frameworkMethod.getTestCase();
        try {
            sNotifier.fireCaseStarted(testCase, this.frameworkMethod.getContext());
            runBeforeCommand(sNotifier, testCase);
            runPipeline(sNotifier, testCase);
        } finally {
            //QJSONReporter qjsonReporter;
            //Map suitMap;
            //List elements;
            //Map lastElement;
            //ParseCase parseCase;
            runTearDownCommand(sNotifier, testCase);
            runAfterCommand(sNotifier, testCase);
            sNotifier.fireCaseFinished(testCase, this.frameworkMethod.getContext());

            QJSONReporter qjsonReporter = (QJSONReporter) this.reporter;
            Map suitMap = qjsonReporter.getSuiteMap();
            List elements = (List) suitMap.get("elements");
            Map lastElement = (Map) elements.get(elements.size() - 1);
            ParseCase parseCase = new ParseCase(qjsonReporter, lastElement);
            new Thread(parseCase).start();
        }
    }

    private void runAfterCommand(StepNotifier sNotifier, TestCase testCase) throws Throwable {
        StepCommand afterCommand = testCase.getAfterCommand();
        if (afterCommand != null)
            afterCommand.execute(null, this.frameworkMethod.getContext(), sNotifier);
    }

    private void runTearDownCommand(StepNotifier sNotifier, TestCase testCase) throws Throwable {
        StepCommand tearDownCommand = testCase.getTearDownCommand();
        if (tearDownCommand != null)
            tearDownCommand.execute(null, this.frameworkMethod.getContext(), sNotifier);
    }

    private void runPipeline(StepNotifier sNotifier, TestCase testCase) throws Throwable {
        StepCommand pipeline = testCase.pipeline();
        if (pipeline != null)
            pipeline.execute(null, this.frameworkMethod.getContext(), sNotifier);
    }

    private void runBeforeCommand(StepNotifier sNotifier, TestCase testCase) throws Throwable {
        StepCommand beforeCommand = testCase.getBeforeCommand();
        if (beforeCommand != null)
            beforeCommand.execute(null, this.frameworkMethod.getContext(), sNotifier);
    }
}